package com.example.demo1.unit;

import com.esri.arcgis.carto.*;
import com.esri.arcgis.datasourcesGDB.SdeWorkspaceFactory;
import com.esri.arcgis.datasourcesfile.ShapefileWorkspaceFactory;
import com.esri.arcgis.display.*;
import com.esri.arcgis.geodatabase.*;
import com.esri.arcgis.geometry.*;
import com.esri.arcgis.output.ExportPNG;
import com.esri.arcgis.system.*;

import java.io.IOException;
import java.util.*;
import java.util.Map;

public class ArcUnit {

    IWorkspace workspace;
    IFeatureWorkspace iFeatureWorkspace;

    public ArcUnit() {
        initializeArcGISLicenses();
        initSde();
        iFeatureWorkspace = (IFeatureWorkspace) workspace;
    }

    /**
     * arcengine创建相关类前的初始化
     */
    private void initializeArcGISLicenses() {
        try {
            EngineInitializer.initializeEngine();
            AoInitialize ao = new AoInitialize();


//            if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) == esriLicenseStatus.esriLicenseAvailable) {
//                ao.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
//            } else
//            if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB) == esriLicenseStatus.esriLicenseAvailable) {
//                ao.initialize(esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB);
//            } else if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeAdvanced) == esriLicenseStatus.esriLicenseAvailable) {
//                ao.initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);
//            }

            ao.initialize(esriLicenseProductCode.esriLicenseProductCodeAdvanced);

            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCode3DAnalyst);
            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeTracking);
            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork);
            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeSpatialAnalyst);
            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeDataInteroperability);
            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeMLE);
            ao.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCodeSchematics);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Description: 初始化Sde库
     *
     * @author: zechen
     * @date: 2022/11/9 15:00
     * @param:
     * @return:
     */
    private void initSde() {
        try {
            PropertySet sdeProperties = new PropertySet();
            sdeProperties.setProperty("SERVER", "localhost");
            sdeProperties.setProperty("INSTANCE", "sde:postgresql:localhost,5432");
            sdeProperties.setProperty("DATABASE", "leims2");
            sdeProperties.setProperty("AUTHENTICATION_MODE", "DBMS");
            sdeProperties.setProperty("USER", "sde");
            sdeProperties.setProperty("PASSWORD", "sde");
            sdeProperties.setProperty("VERSION", "sde.DEFAULT");
//            sdeProperties.setProperty("DB_CLIENT", "postgresql");
            IWorkspaceFactory pSdeFactory = (IWorkspaceFactory) new SdeWorkspaceFactory();
            workspace = pSdeFactory.open(sdeProperties, 2);
            System.out.println("workspace connect success!");

        } catch (IOException e) {
            System.out.println("workspace connect error!");
            e.printStackTrace();
        }
    }

    public IFeatureDataset creteDataSet(String dataSetName, String PRJFilePath) throws IOException {
        PRJFilePath = PRJFilePath == null ? "F:\\桌面\\坐标系\\CGCS2000 3 Degree GK Zone 41.prj" : PRJFilePath;
        ISpatialReferenceFactory iSpatialReferenceFactory = new SpatialReferenceEnvironment();
        ISpatialReference spatialReference = iSpatialReferenceFactory.createESRISpatialReferenceFromPRJFile(PRJFilePath);
        IControlPrecision2 pCP = (IControlPrecision2) spatialReference;
        if (!pCP.isHighPrecision()) {
            pCP.setIsHighPrecision(true);
        }
        return iFeatureWorkspace.createFeatureDataset(dataSetName, spatialReference);

    }

    public List<String> getDataSetNameList() throws IOException {
        List<String> list = new ArrayList<>();
        IEnumDatasetName enumDatasetNam = workspace.getDatasetNames(esriDatasetType.esriDTFeatureDataset);
        IDatasetName datasetName = enumDatasetNam.next();
        while (datasetName != null) {
            list.add(datasetName.getName());
            datasetName = enumDatasetNam.next();
        }
        return list;
    }

    public IFeatureDataset getDataSetByName(String dataSetName) throws IOException {
        return iFeatureWorkspace.openFeatureDataset(dataSetName);
    }

    public void shpToSde(String shpPath, String fileName, String dataSetName, String featureName) throws IOException {

        ShapefileWorkspaceFactory shapefileWorkspaceFactory = new ShapefileWorkspaceFactory();
        Workspace inWorkspace = new Workspace(shapefileWorkspaceFactory.openFromFile(shpPath, 0));
        FeatureClass inFeatureClass = new FeatureClass(inWorkspace.openFeatureClass(fileName + ".shp"));

        IFeatureDataset outDataset = iFeatureWorkspace.openFeatureDataset(dataSetName);
        IFeatureClass outFeatureClass;
        try {
            outFeatureClass = iFeatureWorkspace.openFeatureClass(featureName);
        } catch (Exception e) {
            outFeatureClass = outDataset.createFeatureClass(featureName, inFeatureClass.getFields(),
                    null, null, esriFeatureType.esriFTSimple, inFeatureClass.getShapeFieldName(), "");
        }
        int count = inFeatureClass.featureCount(null);
        for (int i = 0; i < count; i++) {
            IFeature inFeature = inFeatureClass.getFeature(i);
            Polygon polygon = (Polygon) inFeature.getShape();
            if (polygon.isEmpty()) {
                System.out.println("Skipping feature " + i);
                continue;
            }
            Map<String, Object> result = new HashMap<>();
            for (int j = 0; j < inFeature.getFields().getFieldCount(); j++) {
                String fieldName = inFeature.getFields().getField(j).getName();
                String[] keys = {"shape", "fid", "objectid"};
                if (Arrays.asList(keys).contains(fieldName.toLowerCase(Locale.ROOT))) {
                    continue;
                }
                Object val = inFeature.getValue(j);
                if (val != null) {
                    result.put(fieldName.toLowerCase(Locale.ROOT), val);
                }
            }
            Feature feature = (Feature) outFeatureClass.createFeature();
            feature.setShapeByRef(polygon);
            for (int m = 0; m < feature.getFields().getFieldCount(); m++) {
                String name = feature.getFields().getField(m).getName();
                Object val = result.get(name);
                if (val != null)
                    feature.setValue(m, val);
            }
            feature.store();
        }
    }


    private SimpleFillSymbol getSimpleFillSymbol() throws IOException {
        SimpleFillSymbol simpleFillSymbol = new SimpleFillSymbol();
        SimpleLineSymbol lineSymbol = new SimpleLineSymbol();
        lineSymbol.setWidth(2);
        RgbColor red = new RgbColor();
        red.setRGB(0x0000FF);
        lineSymbol.setColor(red);
        simpleFillSymbol.setOutline(lineSymbol);
        simpleFillSymbol.setStyle(esriSimpleFillStyle.esriSFSNull);
        return simpleFillSymbol;
    }

    private TextElement getTextElement(Feature feature) throws IOException {

        Envelope envelope = (Envelope) feature.getExtent().getEnvelope();
        Point point = (Point) envelope.getCentroid();
        RgbColor color = new RgbColor();
        color.setRed(255);
        color.setGreen(0);
        color.setBlue(0);

        TextElement textElement = new TextElement();
        textElement.setText("123456");
        textElement.setColor(color);
        textElement.setGeometry(point);
        textElement.setSize(20.0);
        return textElement;
    }


    private void addText2Page(PageLayout iActiveView, String text, double x, double y) throws IOException {
        TextElement textElement = new TextElement();
        textElement.setText(text);
        textElement.setFontName("宋体");
        Point p = new Point();
        p.setX(x);
        p.setY(y);
        textElement.setGeometry(p);
        textElement.setSize(14.0);
        iActiveView.addElement(textElement, 0);
    }

    /**
     * Description:  返回feature的属性Map
     *
     * @author: zechen
     * @date: 2022/11/18 9:10
     * @param:
     * @return:
     */
    private HashMap<String, Object> getFeatureParams(Feature feature) throws IOException {
        HashMap<String, Object> map = new HashMap<>();
        int count = feature.getFields().getFieldCount();
        for (int i = 0; i < count; i++) {
            String fieldName = feature.getFields().getField(i).getName();
            Object val = feature.getValue(i);
            map.put(fieldName, val);
        }
        return map;
    }

    /**
     * Description: 打印出图
     * Author: zechen
     *
     * @date: 2022/11/18 8:57
     * @param:
     * @return:
     */
    public void testMxd() throws IOException {
        MapDocument mapDocument = new MapDocument();
        mapDocument.open("H:\\springboot-arcobject\\顺德现状图模板3.mxd", null); //打开mxd文件

        PageLayout iActiveView = (PageLayout) mapDocument.getActiveView(); // 获取页面布局
        iActiveView.setShowRulers(true);
        com.esri.arcgis.carto.Map map = (com.esri.arcgis.carto.Map) iActiveView.getFocusMap(); //获取地图
        FeatureLayer featureLayer = (FeatureLayer) map.getLayer(0); // 获取配置好的图层


        iActiveView.selectAllElements();
        IEnumElement iEnumElement = iActiveView.getSelectedElements();
        IElement the_IElement;
        while ((the_IElement = iEnumElement.next()) != null) {
            if (the_IElement.getClass().getName().contains("TextElement")) {
                TextElement textElement = (TextElement) the_IElement;
                System.out.println(textElement.getName() + "输出");
                if (textElement.getText().contains("监测图斑编")) {
                    textElement.setText("监测图斑编号：134645\n" + "图斑面积：56465\n" + "土地坐落：输出");
                }
            }
        }


        //缩放至图斑
        Feature feature = (Feature) featureLayer.getFeatureClass().getFeature(10);
        IEnvelope iEnvelope = feature.getExtent();
        iEnvelope.expand(1.2, 1.2, true);
        map.setMapUnits(esriUnits.esriMeters);
        map.refresh();
        map.setExtent(iEnvelope);


        HashMap<String, Object> params = getFeatureParams(feature);

        CompositeGraphicsLayer graphicsLayer = (CompositeGraphicsLayer) map.getBasicGraphicsLayer();
        graphicsLayer.setSpatialReferenceByRef(map.getSpatialReference());
        PolygonElement polygonElement = new PolygonElement();
        polygonElement.setSymbol(getSimpleFillSymbol());
        polygonElement.setGeometry(feature.getShape());

        graphicsLayer.addElement(getTextElement(feature), 20);
        graphicsLayer.addElement(polygonElement, 10);


//        map.refresh();
//        iActiveView.refresh();

//        IFeatureClass outFeatureClass = iFeatureWorkspace.openFeatureClass("DLTB2020");
//        iFeatureLayer.setFeatureClassByRef(outFeatureClass);

//        mapDocument.saveAs("H:\\springboot-arcobject\\顺德现状图模板3.mxd", false, false);


        double resolution = 300;

        IScreenDisplay iScreenDisplay = iActiveView.getScreenDisplay();

        double screenResolution = iScreenDisplay.getDisplayTransformation().getResolution();
        if (screenResolution <= 0.0) {
            screenResolution = 200;
        }

        // 计算导出范围
        tagRECT rect = new tagRECT();
        rect.left = 0;
        rect.top = 0;
        rect.right = (int) (1.0 * iActiveView.getExportFrame().right * resolution / screenResolution);
        rect.bottom = (int) (1.0 * iActiveView.getExportFrame().bottom * resolution / screenResolution);

        // 设置导出范围
        IEnvelope pEnvelope = new Envelope();
        pEnvelope.putCoords(rect.left, rect.bottom, rect.right, rect.top);

        ExportPNG exportPNG = new ExportPNG();
        // 导出参数
        exportPNG.setResolution(resolution);
        exportPNG.setPixelBounds(pEnvelope);
        exportPNG.setExportFileName("H:\\springboot-arcobject\\1.png");
        exportPNG.setHeight(rect.bottom);
        exportPNG.setWidth(rect.right);

        IEnvelope viewEnvelope = new Envelope();
        viewEnvelope.putCoords(0, 0, 21, 30);
        iActiveView.setExtent(viewEnvelope);

        iActiveView.output(exportPNG.startExporting(), (int) resolution, rect, iActiveView.getExtent(), null);
        exportPNG.finishExporting();
        mapDocument.close();
    }

}
